package com.fourfaith.iot.beidou.manager;

import cn.hutool.core.util.HexUtil;
import com.fazecast.jSerialComm.SerialPort;
import com.fourfaith.iot.beidou.decodec.BeiDouEncoder;
import com.fourfaith.iot.beidou.message.outbound.CCtcqMessage;
import com.fourfaith.iot.beidou.pojo.bean.FkxxBean;
import com.fourfaith.iot.beidou.utils.MessageParseUtil;
import com.fourfaith.iot.beidou.listener.BeiDouListenerImpl;
import com.fourfaith.iot.beidou.utils.BaseCommonFunc;
import com.fourfaith.iot.device.cloud.access.dubbo.pojo.param.BeiDouParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.TimeUnit;

/**
 * @Name SerialPortManager
 * @Description ${}
 * @Author shiyunan
 * @Create 2022/3/4 11:54
 */
@Service
@Slf4j
public class SerialPortManager implements InitializingBean {

    private SerialPort serialPort;

    /**
     * 是否可用
     */
    @Value("${serialPort.enable}")
    private int enable;

    /**
     * 串口名
     */
    @Value("${serialPort.portName}")
    private String portName;

    /**
     * 波特率
     */
    @Value("${serialPort.baudRate}")
    private int baudRate;

    @Autowired
    private BeiDouListenerImpl beiDouListener;

    @Override
    public void afterPropertiesSet() throws Exception {
        if (enable == 1) {
            init(portName, baudRate);
        }
    }

    public SerialPort getSerialPort() {
        return serialPort;
    }

    public void init(String portName, int baudRate) {
        serialPort = SerialPort.getCommPort(portName);
        boolean openPort = serialPort.openPort();
        if (openPort) {
            log.info("串口初始化成功");
        } else {
            log.error("串口初始化失败");
        }
        serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
        serialPort.setComPortParameters(baudRate, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
        serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);
        serialPort.addDataListener(beiDouListener);
    }

    public void close() {
        if (serialPort != null && serialPort.isOpen()) {
            serialPort.closePort();
        }
    }

    public synchronized FkxxBean send(BeiDouParam beiDouParam) throws Exception {
        FkxxBean fkxxBean = new FkxxBean();
        fkxxBean.setDelayTime(0);
        if (enable == 0) {
            fkxxBean.setErrorMessage("未启用");
            fkxxBean.setSuccess(false);
            fkxxBean.setClosed(true);
            return fkxxBean;
        }
        MessageParseUtil.preSend();
        CCtcqMessage cCtcqMessage = new CCtcqMessage();
        cCtcqMessage.setAcceptorNumber(beiDouParam.getReceivedId());
        cCtcqMessage.setFrequencyPoint("2");
        cCtcqMessage.setInboundConfirm("1");
        cCtcqMessage.setEncodingType("3");
        cCtcqMessage.setData("A4" + beiDouParam.getMessageContext());
        cCtcqMessage.setFrequentness("0");
        byte[] data = BeiDouEncoder.encodeToByte(cCtcqMessage);
        if (serialPort == null || !serialPort.isOpen()) {
            log.error("串口未打开");
            fkxxBean.setSuccess(false);
            fkxxBean.setErrorMessage("串口未打开");
            return fkxxBean;
        }
        log.info("串口发送数据：{}", HexUtil.encodeHexStr(data));
        boolean writeResult = serialPort.writeBytes(data, data.length) > 0;

        if (!writeResult) {
            fkxxBean.setErrorMessage("写入失败");
            fkxxBean.setSuccess(false);
            return fkxxBean;
        }

        try {
            boolean await = MessageParseUtil.SEND_LOCK.await(10, TimeUnit.SECONDS);
            if(await){
                FkxxBean sendResult = MessageParseUtil.SEND_RESULT;
                fkxxBean.setDelayTime(0);
                if(sendResult==null){
                    fkxxBean.setErrorMessage("等待超时");
                    fkxxBean.setSuccess(false);
                    return fkxxBean;
                }
                if(sendResult.getSuccess()) {
                    fkxxBean.setErrorMessage("ok");
                    fkxxBean.setSuccess(true);
                    fkxxBean.setDelayTime(sendResult.getDelayTime());
                    return fkxxBean;
                }else {
                    fkxxBean.setErrorMessage("发送失败");
                    fkxxBean.setSuccess(false);
                    return fkxxBean;
                }
            }
        } catch (InterruptedException e) {
            log.error("串口超时未反馈:{}", e.getMessage());
            fkxxBean.setErrorMessage("串口超时未反馈");
            fkxxBean.setSuccess(false);
            return fkxxBean;
        }

        fkxxBean.setErrorMessage("等待超时");
        fkxxBean.setSuccess(false);
        return fkxxBean;
    }




}
